package cn.uncode.baas.server.internal.context;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import cn.uncode.dal.cache.CacheManager;
import cn.uncode.baas.server.acl.token.AccessToken;
import cn.uncode.baas.server.utils.WebApplicationContextUtil;


public class ScriptContext {
	
	private static final ThreadLocal<Integer> scope = new ThreadLocal<Integer>();
	
	private static final ThreadLocal<Map<String, Object>> current = new ThreadLocal<Map<String, Object>>();
	
	private static final ScriptContext context = new ScriptContext();
	
	private static final String SCRIPT_CONTEXT_PREFIX = "script_context_";
	
	private static final int CACHE_OUT_TIME_DEFAULT_SECONDS = 60*40;

    private ScriptContext() {}
    
    public static ScriptContext getInstance() {
        return context;
    }
	
	public static ScriptContext getSession(){
		if(scope.get() == null){
			scope.set(new Integer(1));
		}else{
			scope.set(1);
		}
		return context;
	}
	
	public static ScriptContext getCurrent(){
		if(scope.get() == null){
			scope.set(new Integer(3));
		}else{
			scope.set(3);
		}
		return context;
	}
	
	public static ScriptContext getApplication(){
		if(scope.get() == null){
			scope.set(new Integer(2));
		}else{
			scope.set(2);
		}
		return context;
	}
	
	public Object getAttribute(String name){
		String key = SCRIPT_CONTEXT_PREFIX + RestContextManager.getContext().getBucket();
		CacheManager cacheManager = WebApplicationContextUtil.getBean("cacheManager", CacheManager.class);
		if(null != cacheManager && null != cacheManager.getCache()){
			if(scope.get() == 1){
				String user = String.valueOf(RestContextManager.getContext().getToken().getAdditionalInformation().get(AccessToken.USER));
				if(StringUtils.isNotBlank(user)){
					return cacheManager.getCache().getObject(key + "#" + user + "#" + name);
				}
			}else if(scope.get() == 2){
				return cacheManager.getCache().getObject(key + "#" + name);
			}else if(scope.get() == 3){
				if(null == current.get()){
					return current.get().get(name);
				}
			}
		}
		return null;
	}
	
	@SuppressWarnings("unchecked")
	public Map<String, Object> getHeader(){
		return (Map<String, Object>) getAttribute("header");
	}
	
	public void setAttribute(String name, Object value){
		setAttribute(name, value, CACHE_OUT_TIME_DEFAULT_SECONDS);
	}
	
	public void setAttribute(String name, Object value, int seconds){
		String key = SCRIPT_CONTEXT_PREFIX + RestContextManager.getContext().getBucket();
		CacheManager cacheManager = WebApplicationContextUtil.getBean("cacheManager", CacheManager.class);
		if(null != cacheManager && null != cacheManager.getCache()){
			if(scope.get() == 1){
				String user = String.valueOf(RestContextManager.getContext().getToken().getAdditionalInformation().get(AccessToken.USER));
				if(StringUtils.isNotBlank(user)){
					cacheManager.getCache().putObject(key + "#" + user + "#" + name, value, seconds);
				}
			}else if(scope.get() == 2){
				cacheManager.getCache().putObject(key + "#" + name, value, seconds);
			}else if(scope.get() == 3){
				if(null == current.get()){
					current.set(new HashMap<String, Object>());
				}
				current.get().put(name, value);
			}
		}
	}
	
	public void removeAttribute(String name){
		String key = SCRIPT_CONTEXT_PREFIX + RestContextManager.getContext().getBucket();
		CacheManager cacheManager = WebApplicationContextUtil.getBean("cacheManager", CacheManager.class);
		if(null != cacheManager && null != cacheManager.getCache()){
			if(scope.get() == 1){
				String user = String.valueOf(RestContextManager.getContext().getToken().getAdditionalInformation().get(AccessToken.USER));
				if(StringUtils.isNotBlank(user)){
					cacheManager.getCache().removeObject(key + "#" + user + "#" + name);
				}
			}else if(scope.get() == 2){
				cacheManager.getCache().removeObject(key + "#" + name);
			}else if(scope.get() == 3){
				if(null == current.get()){
					current.get().remove(name);
				}
			}
		}
	}
	
	public String getUser(){
		CacheManager cacheManager = WebApplicationContextUtil.getBean("cacheManager", CacheManager.class);
		if(null != cacheManager && null != cacheManager.getCache()){
			String result = String.valueOf(RestContextManager.getContext().getToken().getAdditionalInformation().get(AccessToken.USER));
			return result;
		}
		return null;
	}
	
	public String getBucket(){
		CacheManager cacheManager = WebApplicationContextUtil.getBean("cacheManager", CacheManager.class);
		if(null != cacheManager && null != cacheManager.getCache()){
			String result = String.valueOf(RestContextManager.getContext().getToken().getAdditionalInformation().get(AccessToken.BUCKET));
			return result;
		}
		return null;
	}

} 
